import { EnvType } from '@/utils/env';

interface WXAccessTokenResponse {
  access_token: string;
  expires_in: number;
  errcode?: number;
  errmsg?: string;
}

type QRCodeType = 'develop' | 'trial' | 'release';

export class WechatService {
  private static instance: WechatService;
  private appId: string;
  private appSecret: string;
  private accessToken: string | null = null;
  private tokenExpireTime: number = 0;

  private constructor() {
    // 从环境变量中读取配置
    const appId = process.env.WECHAT_APP_ID;
    const appSecret = process.env.WECHAT_APP_SECRET;
    if (!appId || !appSecret) {
      throw new Error('WeChat configuration is missing in environment variables');
    }

    this.appId = appId;
    this.appSecret = appSecret;
  }

  public static getInstance(): WechatService {
    if (!WechatService.instance) {
      WechatService.instance = new WechatService();
    }
    return WechatService.instance;
  }

  private async getAccessToken(): Promise<string> {
    // 如果 token 未过期，直接返回
    if (this.accessToken && Date.now() < this.tokenExpireTime) {
      return this.accessToken;
    }

    const url = 'https://api.weixin.qq.com/cgi-bin/stable_token';
    console.log('url', this);
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        grant_type: 'client_credential',
        appid: this.appId,
        secret: this.appSecret,
        force_refresh: false,
      }),
    });

    if (!response.ok) {
      throw new Error(`Failed to get access token: ${response.statusText}`);
    }

    const data: WXAccessTokenResponse = await response.json();

    if (data.errcode) {
      throw new Error(`WeChat API error: ${JSON.stringify(data)}`);
    }

    this.accessToken = data.access_token;
    this.tokenExpireTime = Date.now() + (data.expires_in - 300) * 1000; // 提前5分钟过期

    return this.accessToken;
  }

  public async getQRCode({ path, env, type }: { path: string; env: keyof EnvType; type: QRCodeType }): Promise<string> {
    const response = await fetch('/api/wechat', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        path,
        env,
        type,
      }),
    });

    if (!response.ok) {
      const errorData = await response.json().catch(() => ({ error: response.statusText }));
      throw new Error(`Failed to generate QR code: ${errorData.error || response.statusText}`);
    }

    const data = await response.json();
    return data.url;
  }

  /* env为v1,v5,test */
  // 将原来的 getQRCode 方法重命名为 generateWXACode，供后端使用
  public async generateWXACode(path: string, env: keyof EnvType, type: QRCodeType = 'trial'): Promise<Buffer> {
    const accessToken = await this.getAccessToken();
    // 修改路径格式，确保参数正确编码
    const queryParams = new URLSearchParams({
      env: env,
      scene: type, // 添加场景值用于区分部署类型
    }).toString();
    const fullPath = `${path}?${queryParams}`;
    console.log('fullPath9711', fullPath);
    const url = `https://api.weixin.qq.com/wxa/getwxacode?access_token=${accessToken}`;
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        path: fullPath,
        env_version: type, // 使用传入的 type 参数
        width: 280,
        auto_color: false,
        is_hyaline: false,
      }),
    });

    if (!response.ok) {
      throw new Error(`Failed to generate WXA code: ${response.statusText}`);
    }

    // 检查响应内容类型
    const contentType = response.headers.get('content-type');
    if (contentType?.includes('application/json')) {
      // 如果返回的是 JSON，说明可能有错误信息
      const errorData = await response.json();
      throw new Error(`WeChat API error: ${JSON.stringify(errorData)}`);
    }

    // 如果是图片数据，则转换为 Buffer
    return Buffer.from(await response.arrayBuffer());
  }
}
